<?php

/**
 * Created by PhpStorm.
 * User: soosoogoo
 * Date: 4/27
 * Time: 18:31
 * Desc: Http 监听事件
 */

namespace Listen;

use Config\Code\Error;
use Config\Main;
use Library\Exception\ErrorException;
use ZScript\APP;
use ZScript\Listen\Http as ZScriptHttp;

class Http extends ZScriptHttp
{
    /**
     * worker 进程启动
     * @param $server
     * @param $worker_id
     * @author soosoogoo
     * ------------------------------------------------------------------
     */
    public function onWorkerStart($server, $worker_id)
    {
        parent::onWorkerStart($server, $worker_id); // TODO: Change the autogenerated stub.

        // worker 进程启动时 检测是否有设置默认路由 如果存在默认路由 则初始化进程任务
        $autoRoute = Main::autoRoute();

        if (!$server->taskworker && !empty($autoRoute)) {
            $autoRoute->init();
        }
    }

    /**
     * 进程通信
     * @param \swoole_server $server
     * @param int $src_worker_id
     * @param $message
     * @return mixed
     * @throws
     */
    public function doPipeMessage(\swoole_server $server, $src_worker_id, $message)
    {
        list($params, $action) = \ZScript\Pack\ProcessPack::unpack($message);

        list($controller, $method) = $action;

        return $controller::$method(...$params);
    }

    /**
     * explain
     * @param \swoole_http_request $request
     * @param \swoole_http_response $response
     * @author soosoogoo
     * ------------------------------------------------------------------
     */
    public function onRequest(\swoole_http_request $request, \swoole_http_response $response)
    {
        // TODO : 请求之前先释放静态变量
        \ZScript\Request\Http::destroy();

        // TODO: Implement onRequest() method.
        \ZScript\Request\Http::setRequest($request);
        \ZScript\Response\Http::setResponse($response);

        self::doRequest($request, $response);

        //清空request response $_POST $_GET ...
        \ZScript\Request\Http::destroy();
        \ZScript\Response\Http::destroy();
    }

    /**
     * 处理用户请求操作
     * @param \swoole_http_request $request
     * @param \swoole_http_response $response
     * @return bool
     * @author soosoogoo
     * ------------------------------------------------------------------
     */
    public function doRequest(\swoole_http_request $request, \swoole_http_response $response)
    {
        // TODO: Implement doRequest() method.

        // 加载路由
        $router = new \ZScript\Router\Http();
        $router->autoRoute($request->server['request_uri']);

        try {
            if (!class_exists($router->controllerName())) {
                echo 'have no controller ', $router->controllerName(), PHP_EOL;
                throw new ErrorException(Error::NO_ILLEGAL_OPERATION);
            }

            $controllerName = $router->controllerName();
            $class = new $controllerName();
            $method = $router->methodName();

            if (!method_exists($class, $method)) {
                echo 'have no method ', $method, PHP_EOL;
                throw new ErrorException(Error::NO_ILLEGAL_OPERATION);
            }

            $affect = $class->$method();

            // 返回值查询
            APP::returnHandle($affect);
        } catch (ErrorException $e) {
            // 会停止给客户端回包 造成客户端超时
            return false;
        } catch (\Exception $e) {
            $err_msg = $e->getMessage();

            // 捕获可控异常
            if (is_numeric($err_msg) && $err_msg < 0) {
                $code = $err_msg;
            } else {
                $code = Error::INNER_ERR;
            }

            // 返回值查询
            APP::returnHandle($code);
        }
    }

    /**
     * @param \swoole_server $serv
     * @param  $task_id
     * @param  $src_worker_id
     * @param $data
     * @return
     * ------------------------------------------------------------
     */
    public function onTask(\swoole_server $serv, int $task_id, int $src_worker_id, $data)
    {
        parent::onTask($serv, $task_id, $src_worker_id, $data); // TODO: Change the autogenerated stub

        // 解包
        list($params, $action) = \ZScript\Pack\ProcessPack::unpack($data);

        list($controller, $method) = $action;

        // 故意不检查类下面方法是否存在, 开发自己清楚就行 new 还是 静态 都可以
        $affect = $controller::$method(...$params);

        if ($affect) {
            return $affect;
        }
    }


    public function onFinish(\swoole_server $serv, int $task_id, string $data)
    {
        parent::onFinish($serv, $task_id, $data); // TODO: Change the autogenerated stub

        APP::log('OnFinish ' . json_encode($data));
    }

    public function onClose()
    {

    }

    public function onWorkerStop($server, $worker_id)
    {
        parent::onWorkerStop($server, $worker_id); // TODO: Change the autogenerated stub

        APP::log('Worker shutdown -' . $worker_id);
    }

    public function onWorkerError()
    {
        parent::onWorkerError(); // TODO: Change the autogenerated stub

        APP::log('Worker Error');
    }
}
